import Bun from 'bun';
const { $ } = Bun
import { Ollama } from 'ollama';
//import { downloadWav } from './cosqui/player';
import { downloadWav } from './cosyvoice/player';

const ollama = new Ollama({ http: Bun.env.OLLAMA_ENDPOINT });

let playQ = Promise.resolve();
function playText(text) {
    if (text?.length > 3) {
        playQ = playQ.then(() => downloadWav(text, 'temp.wav'))
            .then(() => $`ffplay -nodisp -autoexit temp.wav`.quiet());
        //.then(()=>new Promise(r=>setTimeout(r, 3000)));
    }
}

function getText(text) {
    const matched = text.match(/"[^"]+"/g);
    if (!matched) {
        return ['', text]
    }
    return [matched.join('.'), text.slice(text.lastIndexOf(matched.at(-1)) + matched.at(-1).length)];
}

Bun.serve({
    port: parseInt(Bun.env.HTTP_PORT),
    async fetch(req) {
        const Url = URL.parse(req.url);
        if (Url.pathname == '/test/tts') {
            playText("Hello, my lover!");
            return new Response('testing... listen');
        }
        const payload = await req.json();
        const resp = await ollama.generate(payload);
        //https://bun.sh/docs/api/streams#async-generator-streams        
        if (payload.stream) {
            let text = '';
            return new Response(async function* () {
                for await (const part of resp) {
                    Bun.stdout.writer().write(part.response);
                    text += part.response;
                    console.log(text);
                    yield `${JSON.stringify(part)}\n`;
                    // const [toPlay, next] = getText(text);
                    // playText(toPlay);
                    // text=next;
                }
                Bun.stdout.writer().write('\n');
                const [toPlay, next] = getText(text);
                playText(toPlay);
            }(), { headers: { 'Content-Type': 'application/x-ndjson' } });
        } else {
            const [toPlay, next] = getText(resp.response);
            playText(toPlay);
            console.log(resp.response);
            return Response.json(resp);
        }
    }
});